package net.mysoft.framework.util;

import java.io.IOException;
import java.io.OutputStream;
import java.util.List;

import org.apache.commons.beanutils.BeanUtils;
import org.apache.log4j.Logger;
import org.apache.poi.hssf.usermodel.HSSFCell;
import org.apache.poi.hssf.usermodel.HSSFRow;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.hssf.util.CellRangeAddress;

public abstract class AbstractReport implements IReport {

	protected static final String NULL_STR = "";

	protected int startRow = 1;

	protected static Logger logger = Logger.getLogger(AbstractReport.class);  
	
	@Override
	public void export(List reportHeads, List reportDatas, OutputStream out) {
		HSSFWorkbook workbook = new HSSFWorkbook();
		exportExcel(workbook, reportHeads, reportDatas);  
		try {
			workbook.write(out);
			out.flush();
		} catch (IOException e) {
			String msg = "导出excel出现错误！";
			logger.error(msg);
		} finally {
			if (null != out) {
				try {
					out.close();
				} catch (IOException e) {
					String msg = "close out stream error";
					logger.error(msg);
				}
			}
		}

	}

	/**
	 * 导出到excel工作薄
	 * 
	 * @param workBook
	 * @param reportHeads
	 * @param reportDatas
	 */
	protected void exportExcel(HSSFWorkbook workBook, List reportHeads,
			List reportDatas) {
		HSSFSheet sheet = exportHeader(workBook, reportHeads);
		exportDatas(workBook, reportHeads, reportDatas, sheet);
	}

	/**
	 * 导出Excel表头
	 * 
	 * @param workBook
	 * @param reportHeads
	 * @return HSSFSheet
	 */
	protected HSSFSheet exportHeader(HSSFWorkbook workBook, List reportHeads) {
		String[] tableHeader = getTableHeader();
		int cellNumber = getCellNumber();
		int colSize = reportHeads.size();
		// 新建Excel表单
		HSSFSheet sheet = workBook.createSheet();
		for (int i = 0; i < colSize; i++) {
			ReportHeader header = (ReportHeader) reportHeads.get(i);
			HSSFRow row = sheet.createRow(i);
			HSSFCell cell = null;
			for (int j = 0; j < cellNumber; j++) {
				cell = row.createCell(j);
				cell.setCellType(HSSFCell.CELL_TYPE_STRING);
				// cell.setCellStyle(SheetStyle.getIndagateHeaderStyle(workBook));
			}
			sheet.addMergedRegion(new CellRangeAddress(i, 0, i,
					(cellNumber - 1)));
			String cellValue = header.getDisplayName();
			if (cellValue == null) {
				cellValue = NULL_STR;
			}
			row.getCell(0).setCellValue(cellValue);
		}
		HSSFRow row = sheet.createRow(colSize);
		for (int k = 0; k < cellNumber; k++) {
			HSSFCell headerCell = row.createCell(k);
			headerCell.setCellType(HSSFCell.CELL_TYPE_STRING);
			headerCell.setCellValue(tableHeader[k]);
		}
		return sheet;
	}

	/**
	 * 设置表的列宽度
	 * 
	 * @param sheet
	 * @param i
	 * @param header
	 */
	protected void formatTableColumns(HSSFSheet sheet, int i,
			ReportHeader header) {
		sheet.setColumnWidth(i, header.getLength());
	}

	/**
	 * 设置表的列宽度
	 * 
	 * @param sheet
	 * @param i
	 * @param header
	 */
	protected void formatTableColumns(HSSFSheet sheet, int i, short length) {
		sheet.setColumnWidth(i, length);
	}

	/**
	 * 设置表的列宽度
	 * 
	 * @param sheet
	 * @param cols
	 * @param header
	 */
	protected void formatTableColumns(HSSFSheet sheet, int[] cols,
			ReportHeader header) {
		if (null == cols || cols.length == 0) {
			return;
		}
		for (int i = 0; i < cols.length; i++) {
			sheet.setColumnWidth(cols[i], header.getLength());
		}

	}

	/**
	 * 设置表的列宽度
	 * 
	 * @param sheet
	 * @param cols
	 * @param lengths
	 */
	protected void formatTableColumns(HSSFSheet sheet, int[] cols,
			short[] lengths) {
		if (null == cols || cols.length == 0 || cols.length != lengths.length) {
			return;
		}
		for (int i = 0; i < cols.length; i++) {
			sheet.setColumnWidth(cols[i], lengths[i]);
		}

	}

	/**
	 * 设置表的列宽度
	 * 
	 * @param sheet
	 * @param cols
	 * @param header
	 */
	protected void formatTableColumns(HSSFSheet sheet, int[] cols, short length) {
		if (null == cols || cols.length == 0) {
			return;
		}
		for (int i = 0; i < cols.length; i++) {
			sheet.setColumnWidth(cols[i], length);
		}

	}

	/**
	 * 返回tableHeader
	 * <p>
	 * 
	 * @return </p>
	 */
	protected abstract String[] getTableHeader();

	/**
	 * 返回cellNumber
	 * <p>
	 * 
	 * @return </p>
	 */
	protected abstract int getCellNumber();

	/**
	 * 返回cellNumber
	 * <p>
	 * 
	 * @return </p>
	 */
	protected abstract String[] getCells();

	/**
	 * 导出reportDatas
	 * 
	 * @param workBook
	 * @param reportHeads
	 * @param reportDatas
	 * @param sheet
	 */
	protected void exportDatas(HSSFWorkbook workBook, List reportHeads,
			List reportDatas, HSSFSheet sheet) {
		// 创建row行的开始
		int size = reportHeads.size() + 1;
		// 创建body数据开始
		sheet.setDefaultColumnWidth(25);
		for (int i = 0; null != reportDatas && i < reportDatas.size(); i++) {
			Object obj = (Object) reportDatas.get(i);
			HSSFRow row = sheet.createRow((short) size + i);
			String[] cells = getCells();
			for (int j = 0; j < cells.length; j++) {
				HSSFCell cell = row.createCell(j);
				cell.setCellType(HSSFCell.CELL_TYPE_STRING);
				try {
					cell.setCellValue(BeanUtils.getProperty(obj, cells[j]));
				} catch (Exception e) {
					e.printStackTrace();
				}
			}
		}
	}

}
